package JavaEE_notes.common_API.Thread;

import JavaEE_notes.common_API.Thread.pojo.MyCallable;
import JavaEE_notes.common_API.Thread.pojo.MyRunnable;

import java.util.concurrent.*;

/**
 * 线程池的练习
 * @author TaiZai
 * @data 2024/9/25 19:32
 */
public class api_ThreadPoolExecutor {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建线程池
        ExecutorService pool = new ThreadPoolExecutor(
                3, // 核心线程数有3个
                5, // 最大线程数有5个   临时线程数的数 = 最大线程数 - 核心线程数
                8, // 临时线程存活的时间8秒， 当临时线程8秒没有执行任务时就会被销毁
                TimeUnit.SECONDS, // 时间单位是秒
                new ArrayBlockingQueue<>(4), // 任务阻塞队列，没有来得及执行的任务在任务队列中等待
                Executors.defaultThreadFactory(), // 用于创建线程的工厂对象
                new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略：当任务队列已满，并且线程池中的线程数小于最大线程数时，新任务会被执行
        );

        // 1、线程执行Runnable任务
        // Runnable task = new MyRunnable();
        // pool.execute(task); // 线程会自动创建一个新线程用来执行这个任务，自动执行
        // pool.execute(task); // 同上
        // pool.execute(task); // 同上

        // 下面这四个任务由于核心线程均在忙，会放入任务队列中排队
        // pool.execute(task);
        // pool.execute(task);
        // pool.execute(task);
        // pool.execute(task);

        // pool.shutdown(); // 关闭线程池，所有任务都执行完毕后再关闭
        // pool.shutdownNow(); // 关闭线程池，不管任务是否执行完毕 立即关闭，并且返回为执行完毕的任务列表

        // 下面这个两个线程由于核心线程均在忙且任务队列已满，会创建临时线程执行
        // pool.execute(task);
        // pool.execute(task);

        // 这个线程由于核心线程和临时线程都在忙且任务队列已满，会拒绝执行，并且由主线程执行其run方法
        // pool.execute(task);

        // 2、线程执行Callable任务
        Future<String> f1 = pool.submit(new MyCallable(100));
        Future<String> f2 = pool.submit(new MyCallable(200));
        Future<String> f3 = pool.submit(new MyCallable(300));
        Future<String> f4 = pool.submit(new MyCallable(400)); // 这个线程会先进入等待队列，等待上面的线程空出核心线程后继续执行

        // 获取返回的结果
        System.out.println(f1.get());
        System.out.println(f2.get());
        System.out.println(f3.get());
        System.out.println(f4.get());

    }
}
